package com.me.flow;

import com.me.flow.service.FlowService;
import com.me.flow.service.FlowServiceImpl;
import lombok.extern.java.Log;
import org.activiti.spring.SpringAsyncExecutor;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.activiti.spring.boot.AbstractProcessEngineAutoConfiguration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.io.IOException;

/**
 * @title: FlowConfig
 * @description: 工作流数据源配置
 * @date 2021-07-23
 */
@Log
@Configuration
@EnableConfigurationProperties
@MapperScan(basePackages = "com.me.flow.mapper", sqlSessionTemplateRef = "flowSqlSessionTemplate")
public class FlowConfiguration extends AbstractProcessEngineAutoConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "spring.flow-datasource")
    public DataSource flowDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public SpringProcessEngineConfiguration springProcessEngineConfiguration(
            PlatformTransactionManager transactionManager,
            SpringAsyncExecutor springAsyncExecutor) throws IOException {

        return baseSpringProcessEngineConfiguration(
                flowDataSource(),
                transactionManager,
                springAsyncExecutor);
    }

    @Bean
    public SqlSessionFactory flowSqlSessionFactory(
            @Qualifier("flowDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapper/flow/*.xml"));
        return bean.getObject();
    }

    @Bean
    public DataSourceTransactionManager flowTransactionManager(@Qualifier("flowDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    public SqlSessionTemplate flowSqlSessionTemplate(
            @Qualifier("flowSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean(name = "flowService")
    public FlowService flowService() {
        return new FlowServiceImpl();
    }

}
